<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>朵朵视野-Three.js模拟实现地月绕太阳自转体系</title>
    <link href="./css/index.css" rel="stylesheet">
    <link href="./css/font/font-awesome.min.css" rel="stylesheet">
    <script type="text/javascript" src="./js/three.min.js"></script>
    <script type="text/javascript" src="./js/OrbitControls.js"></script>
</head>
<body>
	<ul id="starry-lite">
		<li><p>太阳：</p><img src="./image/sun_min_bg.png" /></li>
		<li><p>地球：</p><img src="./image/earth_min_bg.png" /></li>
		<li><p>月球：</p><img src="./image/moon_min_bg.png" /></li>
	</ul>
	<div id="starry-frame"></div>
	</body>
	<script>
	    // 渲染器
	    var renderer = null;
	    // 相机
	    var camera = null;
	    // 场景
	    var scene = null;
	    // 中心球体（太阳）
	    var centerBall = null;
	    // 中心球体轨道组合体（行星）
	    var starLites = [];
	    // 包裹画布dom
	    var dom = document.getElementById("starry-frame");
	    // 太阳自转速度
	    var sunSpeed = 0.01;
	    // 太阳大小
	    var sunSize = 30;
	    // 太阳光照放大率
	    var sunScaleSize = 110;
	    // 太阳光颜色
	    var sunSpriteColor = '253,111,7';
	    // 太阳贴图
	    var sunImgUrl = './image/sun_bg.jpg';
	    // orbitcontrols对象参数
	    var orbitcontrols = null;
	    // 地月体系变量
	    var earthMesh = null;
	    // 地球变量
	    var earthLite = null;
	    // 地球公转半径
	    var earthLiteRadius = 42.2;
	    // 地球贴图
	    var imgUrl = './image/earth_bg.jpg';
	    // 地球大小
	    var earthLiteSize = 5.2;
	    // 地球rotation
	    var rotation = {
	    	x: -Math.PI * 0.42, 
	    	y: Math.PI * 0.02, 
	    	z: 0
	    }
	    // 地球公转速度
	    var earthRotationSpeed = 0.016;
	    // 地球自转速度
	    var earthSpeed = 0.025;
	    // 月球对象
	    var moonLite = null;
	    // 月球大小
	    var moonLiteSize = 2.5;
	    // 月球贴图
	    var imgMoonUrl = './image/moon_bg.jpg';
	    // 月球3d对象
	    var moonPoint = null;
	    // 月球公转速度
	    var moonSpeed = 0.02;
	    // 月球自转速度
	    var moonLiteSpeed = 0.21;
	    /**
	     * 实现球体发光
	     * @param color 颜色的r,g和b值,比如：“123,123,123”;
	     * @returns {Element} 返回canvas对象
	     */
	    var generateSprite = function (color) {
	        var canvas = document.createElement('canvas');
	        canvas.width = 16;
	        canvas.height = 16;
	        var context = canvas.getContext('2d');
	        var gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
	        gradient.addColorStop(0, 'rgba(' + color + ',1)');
	        gradient.addColorStop(0.2, 'rgba(' + color + ',1)');
	        gradient.addColorStop(0.4, 'rgba(' + color + ',.6)');
	        gradient.addColorStop(1, 'rgba(0,0,0,0)');
	        context.fillStyle = gradient;
	        context.fillRect(0, 0, canvas.width, canvas.height);
	        return canvas;
	    };
	    // 创建地月体系
	    var createSearthLite = function () {
	    	// 添加地月体系
	        earthMesh = new THREE.Mesh(new THREE.SphereGeometry(1, 1, 1), new THREE.MeshLambertMaterial()); //材质设定
	        // 地球对应元素
	        // 地球公转轨道
	        var track = new THREE.Mesh(new THREE.RingGeometry(earthLiteRadius, earthLiteRadius + 0.05, 50, 1), new THREE.MeshBasicMaterial());
	        earthLite = new THREE.Mesh(new THREE.SphereGeometry(earthLiteSize, 30, 30), new THREE.MeshPhongMaterial({
	        	map: THREE.ImageUtils.loadTexture(imgUrl)
	        }));
	        earthLite.position.set(earthLiteRadius, 0, 0);
	        // 月球对应元素
	        // 月球公转轨道
	        var trackMoon = new THREE.Mesh(new THREE.RingGeometry(earthLiteSize + 4, earthLiteSize + 4.05, 50, 1), new THREE.MeshBasicMaterial());
	        moonLite = new THREE.Mesh(new THREE.SphereGeometry(moonLiteSize, 30, 30), new THREE.MeshPhongMaterial({
	        	map: THREE.ImageUtils.loadTexture(imgMoonUrl)
	        }));
	        // 月球公转轨道中心
	        moonLite.position.set(earthLiteSize + 4, 0, 0);
	        moonPoint = new THREE.Object3D();
	        moonPoint.add(trackMoon);
	        moonPoint.add(moonLite);
	        moonPoint.position.set(earthLiteRadius, 0, 0);
	        
	        var earthPoint = new THREE.Object3D();
	        earthPoint.add(earthLite);
	        earthPoint.add(track);
	        earthPoint.add(moonPoint);
	        earthMesh.add(earthPoint);
	        earthMesh.rotation.set(rotation.x, rotation.y, rotation.z);
	        scene.add(earthMesh);
	    }
	    // 执行函数
	    var render = function () {
	        renderer.render(scene, camera);
	        centerBall.rotation.y -= sunSpeed;
	        earthMesh.rotation.z -= earthRotationSpeed;
	        earthLite.rotation.z -= earthSpeed;
	        moonLite.rotation.z -= moonLiteSpeed;
	        moonPoint.rotation.z -= moonSpeed;
	    	orbitcontrols.update();
	        requestAnimationFrame(render);
	    }
	    // 初始化函数
	    var initThree = function () {
	        // 初始化场景
	        scene = new THREE.Scene();
	        // 初始化相机
	        camera = new THREE.PerspectiveCamera(20, dom.clientWidth / dom.clientHeight, 1, 1000);
	        // 设置相机位置
	        camera.position.set(0, 0, 300);
	        renderer = new THREE.WebGLRenderer({
	            alpha: true,
	            antialias: true
	        });
	        // 设置光照
	        var lights = new THREE.PointLight('#ffffff', 1);
	        lights.position.set(0, 0, 0);
	        scene.add(lights);
	        // 设置窗口尺寸
	        renderer.setSize(dom.clientWidth, dom.clientHeight);
	        // 初始化控制器
	        orbitcontrols = new THREE.OrbitControls(camera,renderer.domElement);
	        dom.appendChild(renderer.domElement);
	        // 定义太阳材质
	        var sunTexture = THREE.ImageUtils.loadTexture(sunImgUrl, {}, function () {
	            renderer.render(scene, camera);
	        });
	        // 太阳以及太阳材质设定
	        centerBall = new THREE.Mesh(new THREE.SphereGeometry(sunSize, 30, 50), new THREE.MeshBasicMaterial({
	            map: sunTexture
	        }));
	        // 添加太阳发光效果
	        var centerBallLite = new THREE.Sprite(new THREE.SpriteMaterial({
	            map: new THREE.CanvasTexture(generateSprite(sunSpriteColor)),
	            blending: THREE.AdditiveBlending
	        }));
	        centerBallLite.scale.x = centerBallLite.scale.y = centerBallLite.scale.z = sunScaleSize;
	        scene.add(centerBallLite);
	        scene.add(centerBall);
	        // 地月体系
	        createSearthLite();
	        // 渲染
	        render();
	    }
	    // 页面资源加载完全执行函数
	    window.onload = function () {
	    	initThree()
	    }
	    // 窗口resize事件
	    window.onresize = function () {
	    	// 重新初始化尺寸
	        camera.aspect = dom.clientWidth / dom.clientHeight
	        camera.updateProjectionMatrix()
	        renderer.setSize(dom.clientWidth, dom.clientHeight)
	    }
	</script>
</html>